home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / aspisrc.zip / TAR.C < prev    next >
C/C++ Source or Header  |  1992-01-26  |  33KB  |  1,316 lines

  1. /* Tar -- a tape archiver.
  2.  
  3.     Copyright (C) 1988 Free Software Foundation
  4.  
  5. GNU tar is distributed in the hope that it will be useful, but WITHOUT ANY
  6. WARRANTY.  No author or distributor accepts responsibility to anyone
  7. for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.
  9. Refer to the GNU tar General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute GNU tar,
  12. but only under the conditions described in the GNU tar General Public
  13. License.  A copy of this license is supposed to have been given to you
  14. along with GNU tar so you can know your rights and responsibilities.  It
  15. should be in a file named COPYING.  Among other things, the copyright
  16. notice and this notice must be preserved on all copies.
  17.  
  18. In other words, go ahead and share GNU tar, but don't try to stop
  19. anyone else from sharing it farther.  Help stamp out software hoarding!
  20. */
  21.  
  22. /*
  23.  * A tar (tape archiver) program.
  24.  *
  25.  * Written by John Gilmore, ihnp4!hoptoad!gnu, starting 25 Aug 85.
  26.  *
  27.  * @(#)tar.c 1.34 11/6/87 - gnu
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <sys/types.h>        /* Needed for typedefs in tar.h */
  32. #include <sys/stat.h>        /* JF */
  33. #include "getopt.h"
  34. #include "regex.h"
  35.  
  36. #ifdef USG
  37. #define rindex strrchr
  38. #endif
  39.  
  40. #ifdef BSD42
  41. #include <sys/dir.h>
  42. #else
  43. #ifdef __MSDOS__
  44. #include "msd_dir.h"
  45. #else
  46. #ifdef USG
  47. #ifdef NDIR
  48. #include <ndir.h>
  49. #else
  50. #include <dirent.h>
  51. #endif
  52. #ifndef DIRECT
  53. #define direct dirent
  54. #endif
  55. #define DP_NAMELEN(x) strlen((x)->d_name)
  56. #else
  57. /*
  58.  * FIXME: On other systems there is no standard place for the header file
  59.  * for the portable directory access routines.  Change the #include line
  60.  * below to bring it in from wherever it is.
  61.  */
  62. #include "ndir.h"
  63. #endif
  64. #endif
  65. #endif
  66.  
  67. #ifndef DP_NAMELEN
  68. #define DP_NAMELEN(x)    (x)->d_namlen
  69. #endif
  70.  
  71. extern char     *malloc();
  72. extern char     *getenv();
  73. extern char    *strncpy();
  74. extern char    *index();
  75. extern char    *strcpy();    /* JF */
  76. extern char    *strcat();    /* JF */
  77.  
  78. extern char    *optarg;    /* Pointer to argument */
  79. extern int    optind;        /* Global argv index from getopt */
  80.  
  81. extern char     *ck_malloc();
  82. extern char     *ck_realloc();
  83. /*
  84.  * The following causes "tar.h" to produce definitions of all the
  85.  * global variables, rather than just "extern" declarations of them.
  86.  */
  87. #define TAR_EXTERN /**/
  88. #include "tar.h"
  89.  
  90. /*
  91.  * We should use a conversion routine that does reasonable error
  92.  * checking -- atoi doesn't.  For now, punt.  FIXME.
  93.  */
  94. #define intconv    atoi
  95. extern int    getoldopt();
  96. extern void    read_and();
  97. extern void    list_archive();
  98. extern void    extract_archive();
  99. extern void    diff_archive();
  100. extern void    create_archive();
  101. extern void    update_archive();
  102. extern void    junk_archive();
  103.  
  104. /* JF */
  105. extern time_t    get_date();
  106.  
  107. time_t new_time;
  108.  
  109. static FILE    *namef;        /* File to read names from */
  110. static char    **n_argv;    /* Argv used by name routines */
  111. static int    n_argc;        /* Argc used by name routines */
  112. static char    **n_ind;    /* Store an array of names */
  113. static int    n_indalloc;    /* How big is the array? */
  114. static int    n_indused;    /* How many entries does it have? */
  115. static int    n_indscan;    /* How many of the entries have we scanned? */
  116.  
  117.  
  118. extern FILE *msg_file;
  119.  
  120. void    describe();
  121. void    options();
  122.  
  123. #ifndef S_IFLNK
  124. #define lstat stat
  125. #endif
  126.  
  127. #ifndef DEFBLOCKING
  128. #define DEFBLOCKING 20
  129. #endif
  130.  
  131. #ifndef DEF_AR_FILE
  132. #define DEF_AR_FILE "tar.out"
  133. #endif
  134.  
  135. /* For long options that unconditionally set a single flag, we have getopt
  136.    do it.  For the others, we share the code for the equivalent short
  137.    named option, the name of which is stored in the otherwise-unused `val'
  138.    field of the `struct option'; for long options that have no equivalent
  139.    short option, we use nongraphic characters as pseudo short option
  140.    characters, starting (for no particular reason) with character 10. */
  141.  
  142. struct option long_options[] =
  143. {
  144.     {"create",        0,    0,            'c'},
  145.     {"append",        0,    0,            'r'},
  146.     {"extract",        0,    0,            'x'},
  147.     {"get",            0,    0,            'x'},
  148.     {"list",        0,    0,            't'},
  149.     {"update",        0,    0,            'u'},
  150.     {"catenate",        0,    0,            'A'},
  151.     {"concatenate",        0,    0,            'A'},
  152.     {"compare",        0,    0,            'd'},
  153.     {"diff",        0,    0,            'd'},
  154.     {"delete",        0,    0,            14},
  155.     {"help",        0,    0,            12},
  156.  
  157.     {"directory",        1,    0,            'C'},
  158.     {"record-number",    0,    &f_sayblock,        1},
  159.     {"files-from",        1,    0,            'T'},
  160.     {"label",        1,    0,            'V'},
  161.     {"exclude-from",    1,    0,            'X'},
  162.     {"exclude",        1,    0,            15},
  163.     {"file",        1,    0,            'f'},
  164.     {"block-size",        1,    0,            'b'},
  165.     {"version",        0,    0,            11},
  166.     {"verbose",         0,    0,            'v'},
  167.     {"totals",        0,    &f_totals,        1},
  168.       
  169.     {"read-full-blocks",    0,    &f_reblock,        1},
  170.     {"starting-file",    1,    0,            'K'},
  171.     {"to-stdout",        0,    &f_exstdout,        1},
  172.     {"ignore-zeros",    0,    &f_ignorez,        1},
  173.     {"keep-old-files",    0,    0,            'k'},
  174.     {"uncompress",        0,    &f_compress,        1},
  175.     {"same-permissions",    0,    &f_use_protection,    1},
  176.     {"preserve-permissions",0,    &f_use_protection,    1},
  177.     {"modification-time",    0,    &f_modified,        1},
  178.     {"preserve",        0,    0,            10},
  179.     {"same-order",        0,    &f_sorted_names,    1},
  180.     {"same-owner",        0,    &f_do_chown,        1},
  181.     {"preserve-order",    0,    &f_sorted_names,    1},
  182.  
  183.     {"newer",        1,    0,            'N'},
  184.     {"after-date",        1,    0,            'N'},
  185.     {"newer-mtime",        1,    0,            13},
  186.     {"incremental",        0,    0,            'G'},
  187.     {"listed-incremental",    1,    0,            'g'},
  188.     {"multi-volume",    0,    &f_multivol,        1},
  189.     {"info-script",        1,    &f_run_script_at_end,    1},
  190.     {"absolute-paths",    0,    &f_absolute_paths,    1},
  191.     {"interactive",        0,    &f_confirm,        1},
  192.     {"confirmation",    0,    &f_confirm,        1},
  193.  
  194.     {"verify",        0,    &f_verify,        1},
  195.     {"dereference",        0,    &f_follow_links,    1},
  196.     {"one-file-system",    0,    &f_local_filesys,     1},
  197.     {"old-archive",        0,    0,            'o'},
  198.     {"portability",        0,    0,            'o'},
  199.     {"compress",        0,    &f_compress,        1},
  200.     {"compress-block",    0,    &f_compress,        2},
  201.     {"sparse",        0,    &f_sparse_files,    1},
  202.     {"tape-length",        1,    0,            'L'},
  203.  
  204.     {0, 0, 0, 0}
  205. };
  206.  
  207. /*
  208.  * Main routine for tar.
  209.  */
  210. main(argc, argv)
  211.     int    argc;
  212.     char    **argv;
  213. {
  214.     extern char version_string[];
  215.  
  216.     tar = argv[0];        /* JF: was "tar" Set program name */
  217.     errors = 0;
  218.  
  219.     options(argc, argv);
  220.  
  221.     if(!n_argv)
  222.         name_init(argc, argv);
  223.  
  224.     switch(cmd_mode) {
  225.     case CMD_CAT:
  226.     case CMD_UPDATE:
  227.     case CMD_APPEND:
  228.         update_archive();
  229.         break;
  230.     case CMD_DELETE:
  231.         junk_archive();
  232.         break;
  233.     case CMD_CREATE:
  234.         create_archive();
  235.         if (f_totals)
  236.             fprintf (stderr, "Total bytes written: %d\n", tot_written);
  237.         break;
  238.     case CMD_EXTRACT:
  239.         if (f_volhdr) {
  240.             char *err;
  241.             label_pattern = (struct re_pattern_buffer *)
  242.               ck_malloc (sizeof *label_pattern);
  243.              err = re_compile_pattern (f_volhdr, strlen (f_volhdr),
  244.                           label_pattern);
  245.             if (err) {
  246.                 fprintf (stderr,"Bad regular expression: %s\n",
  247.                      err);
  248.                 errors++;
  249.                 break;
  250.             }
  251.            
  252.         }          
  253.         extr_init();
  254.         read_and(extract_archive);
  255.         break;
  256.     case CMD_LIST:
  257.         if (f_volhdr) {
  258.             char *err;
  259.             label_pattern = (struct re_pattern_buffer *)
  260.               ck_malloc (sizeof *label_pattern);
  261.              err = re_compile_pattern (f_volhdr, strlen (f_volhdr),
  262.                           label_pattern);
  263.             if (err) {
  264.                 fprintf (stderr,"Bad regular expression: %s\n",
  265.                      err);
  266.                 errors++;
  267.                 break;
  268.             }
  269.         }          
  270.         read_and(list_archive);
  271. #if 0
  272.         if (!errors)
  273.             errors = different;
  274. #endif
  275.         break;
  276.     case CMD_DIFF:
  277.         diff_init();
  278.         read_and(diff_archive);
  279.         break;
  280.     case CMD_VERSION:
  281.         fprintf(stderr,"%s\n",version_string);
  282.         break;
  283.     case CMD_NONE:
  284.         msg("you must specify exactly one of the r, c, t, x, or d options\n");
  285.          fprintf(stderr,"For more information, type ``%s +help''.\n",tar);
  286.         exit(EX_ARGSBAD);
  287.     }
  288.     exit(errors);
  289.     /* NOTREACHED */
  290. }
  291.  
  292.  
  293. /*
  294.  * Parse the options for tar.
  295.  */
  296. void
  297. options(argc, argv)
  298.     int    argc;
  299.     char    **argv;
  300. {
  301.     register int    c;        /* Option letter */
  302.     int        ind = -1;
  303.  
  304.     /* Set default option values */
  305.     blocking = DEFBLOCKING;        /* From Makefile */
  306.     ar_file = getenv("TAPE");    /* From environment, or */
  307.     if (ar_file == 0)
  308.         ar_file = DEF_AR_FILE;    /* From Makefile */
  309.  
  310.     /* Parse options */
  311.     while ((c = getoldopt(argc, argv,
  312.                   "-01234567Ab:BcC:df:F:g:GhikK:lL:mMN:oOpPrRsStT:u